/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// const { tokens } = require('./jsTokens') 
import tokens from './jsTokens'  

const BASE_COUNT=10000;


/* test String */
function default_Test_01() {    
    let defaultValue
    const testData =  "'string'code'another string ' When dusk had fallen,I should experience the double delight of being able to see by artificial light which the genius of man has created to extend the power of his sight when Nature decrees darkness.On that busy first day I should also view the small simple things of my home. I want to see the warm colors in the rugs under my feet, the pictures on the walls, the intimate trifles that transform a house into home. My eyes would rest respectfully on the books in raised type which I have read, but they would be more eagerly interested in the printed books which seeing people can read, for during the long night of my life the books I have read and those which have been read to me have built themselves into a great shining lighthouse, revealing to me the deepest channels of human life and the human spirit." 
    let startTime =  Date.now()   
    for (let index = 0; index < BASE_COUNT; index++) { 
        tokens.default.lastIndex = 0 
        defaultValue = tokens.default.exec(testData)
    }
    let endTime =  Date.now()
    let time = endTime - startTime
    print("jsTokens_Default(string): " + time +" ms")  
    let token = tokens.matchToToken(defaultValue)
    match(token, "string", testData, "'string'")

    // print(token) 
}
/* test whitespace */
function default_Test_02() {    
    let defaultValue
    const testData =  " \t\n\r \r\n-1 "
    let startTime =  Date.now()   
    for (let index = 0; index < BASE_COUNT; index++) { 
        tokens.default.lastIndex = 0 
        defaultValue = tokens.default.exec(testData)
    } 
    let endTime =  Date.now()
    let time = endTime - startTime
    print("jsTokens_Default(whitespace): " + time +" ms")  
    let token = tokens.matchToToken(defaultValue)
    match(token, "whitespace", testData, " \t\n\r \r\n")

    // print(token) 
}
/* test comment */
function default_Test_03() {    
    let defaultValue
    const testData = "//comment\u2029" 
    let startTime =  Date.now()   
    for (let index = 0; index < BASE_COUNT; index++) { 
        tokens.default.lastIndex = 0 
        defaultValue = tokens.default.exec(testData)
    }  
    let endTime =  Date.now()
    let time = endTime - startTime
    print("jsTokens_Default(comment): " + time +" ms")  
    let token = tokens.matchToToken(defaultValue)
    match(token, "comment", testData, "//comment")

    // print(token) 
}
  

/* test Number */
function matchToToken_Test_01() {   
    tokens.default.lastIndex = 0  
    const testData = "4165456126564651654654436124466532144653244562134153664654675665496556794658704659874654876557464755646634452341532342156154461354462345465144362544163254416532445326153243152416545612656465165465443612446653214465324456213415366465467566549655679465870465987465487655746475564663445234153234215615446135446234546514436254416325441653244532615324315241654561265646516546544361244665321446532445621341536646546756654965567946587046598746548765574647556466344523415323421561544613544623454651443625441632544165324453261532431524165456126564651654654436124466532144653244562134153664654675665496556794658704659874654876557464755646634452341532342156154461354462345465144362544163254416532445326153243152416545612656465165465443612446653214465324456213415366465467566549655679465870465987465487655746475564663445234153234215615446135446234546514436254416325441653244532615324315241654561265646516546544361244665321446532445621341536646546756654965567946587046598746548765574647556466344523415323421561544613544623454651443625441632544165324453261532431524165456126564651654654436124466532144653244562134153664654675665496556794658704659874654876557464755646634452341532342156154461354462345465144362544163254416532445326153243152416545612656465165465443612446653214465324456213415366465467566549655679465870465987465487655746475564663445234153234215615446135446234546514436254416325441653244532615324315241654561265646516546544361244665321446532445621341536646546756654965567946587046598746548765574647556466344523415323421561544613544623454651443625441632544165324453261532431524165456126564651654654436124466532144653244562134153664654675665496556794658704659874654876557464755646634452341532342156154461354462345465144362544163254416532445326153243152"
    let defaultValue = tokens.default.exec(testData)
    let token
    let startTime =  Date.now()
    for (let index = 0; index < 100000; index++) { 
        token = tokens.matchToToken(defaultValue)
    }
    let endTime =  Date.now() 
    let time = endTime - startTime
    print("jsTokens_MatchToToken(number): " + time +" ms") 
    match(token, "number", testData)   

    // print(token)
}
/* test Number */
function matchToToken_Test_02() {   
    tokens.default.lastIndex = 0  
    const testData = "/invalid escape sequence is OK: \\u/"
    let defaultValue = tokens.default.exec(testData)
    let token
    let startTime =  Date.now()
    for (let index = 0; index < 100000; index++) { 
        token = tokens.matchToToken(defaultValue)
    }
    let endTime =  Date.now() 
    let time = endTime - startTime
    print("jsTokens_MatchToToken(regex): " + time +" ms") 
    match(token, "regex", testData)   

    // print(token)
}
/* test Number */
function matchToToken_Test_03() {   
    tokens.default.lastIndex = 0  
    const testData = "Iñtërnâtiônàlizætiøn☃💩When dusk had fallen,I should experience the double delight of being able to see by artificial light which the genius of man has created to extend the power of his sight when Nature decrees darkness.On that busy first day I should also view the small simple things of my home. I want to see the warm colors in the rugs under my feet, the pictures on the walls, the intimate trifles that transform a house into home. My eyes would rest respectfully on the books in raised type which I have read, but they would be more eagerly interested in the printed books which seeing people can read, for during the long night of my life the books I have read and those which have been read to me have built themselves into a great shining lighthouse, revealing to me the deepest channels of human life and the human spirit"
    let defaultValue = tokens.default.exec(testData)
    let token
    let startTime =  Date.now()
    for (let index = 0; index < 100000; index++) { 
        token = tokens.matchToToken(defaultValue)
    }
    let endTime =  Date.now() 
    let time = endTime - startTime
    print("jsTokens_MatchToToken(name): " + time +" ms") 
    match(token, "name", "Iñtërnâtiônàlizætiøn☃💩When")   

    // print(token)
}

 
 
 
//Verification Method
function match(tokens, type, value, expected, extra) {
    extra = extra || {}
    if (typeof expected === "object") {
      extra = expected
      expected = undefined
    } 
    if(value){
      let token = tokens
      if (expected === false) {
        areNotEqual(token.type,type) 
      } else { 
        areEqual(token.type,type); 
        areEqual(typeof expected === "string" ? expected : value,token.value);
        let objKeys = getKeys(extra)
        if (objKeys.indexOf("closed") !== -1) { 
          areEqual(token.closed,extra.closed); 
        } else if (type === "string") { 
          areEqual(token.closed,true); 
        }
      }
    //   print(`test data： ${value}  result: ${JSON.stringify(token)}`)
    }
}
function getKeys(obj) {
    let keys = Object.keys(obj);
    return keys;
}
 
/* Expected results and actual results verification  */
function areEqual(expected, actual) {
    // If expected and actual are both NaN, consider them equal.
    if (expected === actual || expected !== expected && actual !== actual) {
        // print('Success')
    } else {
        let error = 
        '  Failed areEqual test' +
        '  Expected: ' + expected +
        '  Actual:   ' + actual
        ;
        throw(error) 
    }
}
/* Expected results and actual results verification  */
function areNotEqual(expected, actual) { 
    if (expected !== actual) {
        // print('Success')
    } else {
        let error = 
        '  Failed areEqual test' +
        '  Expected: ' + expected +
        '  Actual:   ' + actual
        ;
        throw(error) 
    }
}
 

/*  Benchmark  */
function jsTokensRun() { 
    default_Test_01()
    default_Test_02()
    default_Test_03() 
    
    matchToToken_Test_01() 
    matchToToken_Test_02() 
    matchToToken_Test_03()
} 
let loopCountForPreheat = 1;
for (let i = 0; i < loopCountForPreheat; i++) {
    jsTokensRun()
}

ArkTools.waitAllJitCompileFinish();

jsTokensRun()


// function print(s){
//     console.log(s)
// }

